/**
 * 1.封装全局接口请求axios
 * 2.进行大数不精确处理
 */
// 导入axios
import axios from 'axios'
// 导入router实例
import router from '../router'
// 导入大数处理
import JSONBIGINT from 'json-bigint'
// 导入store
import store from '../store'
// 配置axios
const MyAxios = axios.create({
  baseURL: 'http://ttapi.research.itcast.cn/app/v1_0/',
  transformResponse: [function (data) {
    try {
      return JSONBIGINT.parse(data)
    } catch (error) {
      return data
    }
  }]
})
// axios请求前的拦截器
MyAxios.interceptors.request.use(function (config) {
// 请求发送之前,统一往请求头中添加token
// 判断当前本地是否有token并且判断的当前是否在登录页
  if (store.state.user.token && config.url !== 'authorizations') {
    config.headers.Authorization = `Bearer ${store.state.user.token}`
  }
  // 处理接口版本问题
  if (config.url === 'articles') {
    config.baseURL = config.baseURL.replace('v1_0', 'v1_1')
  }
  return config
}, function (error) {
  return Promise.reject(error)
})
// axios请求后数据返回前的拦截器
MyAxios.interceptors.response.use(function (response) {
  // 统一简化返回的数据
  return {
    status: response.status,
    data: response.data.data
  }
},
async function (error) {
  // 跳转路由(没登录过或者双token失效)
  const loginConfig = { path: '/login', query: { redirectUrl: router.currentRoute.path } }
  // 拿到token数据(查看是否登陆过)
  const { user } = store.state
  try {
    if (error.response && error.response.status === 401) {
      // 1.没登录过=>从新登陆
      if (!user.token || !user.refresh_token) {
        router.push(loginConfig)
        return Promise.reject(error)
      }
      // 2.登陆过=>token失效但refresh_token没失效=>刷新token(携带refresh_token从新调用接口)
      const { status, data } = await MyAxios.put('authorizations', null, {
        headers: {
          Authorization: `Bearer ${user.refresh_token}`
        }
      })
      // 获取到最新的token了
      if (status === 201) {
        store.commit('setToken', {
          // 更新本地的token
          token: data.token,
          // refresh_token没过期继续赋值回去
          refresh_token: user.refresh_token
        })
        // 重新再调用上次401失败的请求
        MyAxios(error.cofing)
      }
    }
  } catch (error) {
    // 3.双token都失效
    router.push(loginConfig)
    return Promise.reject(error)
  }
  return Promise.reject(error)
})
// 封装vue插件
const MyAxiosPlug = function (Vue) {
  Vue.prototype.request = MyAxios
}
// 导出插件
export { MyAxiosPlug }
// 导出axios
export default MyAxios
